package net.longjin.bootdmdemo.core;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ：HuChao
 * @date ：Created in 2020/12/21 10:10
 * @description：全局请求响应日志拦截
 * @modified By：
 */
@Aspect
@Component
@Slf4j
public class GlobalLogAspect {
    public static final ThreadLocal<Long> threadLocal = new ThreadLocal<Long>();

    @Pointcut(value = "(execution(* net.longjin.bootdmdemo.controller.*.*(..))))")
    public void webLog() {

    }

    //指定切点前的处理方法
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Exception {
        threadLocal.set(System.currentTimeMillis());
        //获取request对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        StringBuilder sb = new StringBuilder();
        //拼接请求内容
        sb.append("\n[请求路径]:").append(request.getRequestURL().toString()).append("  ").append(request.getMethod()).append("\n");
        //判断请求是什么请求
        if (request.getMethod().equalsIgnoreCase(RequestMethod.GET.name())) {
            Map<String, String[]> parameterMap = request.getParameterMap();
            Map<String, String> paramMap = new HashMap<>();
            parameterMap.forEach((key, value) -> paramMap.put(key, String.join(",", value)));
            sb.append("[请求参数]:").append(JSON.toJSONString(paramMap));
        } else if (request.getMethod().equalsIgnoreCase(RequestMethod.POST.name())) {
            Object[] args = joinPoint.getArgs();
            StringBuilder stringBuilder = new StringBuilder();
            Arrays.stream(args).forEach(obj -> stringBuilder.append(obj.toString().replace("=", ":")));
            if (stringBuilder.length() == 0) {
                stringBuilder.append("{}");
            }
            sb.append("[请求参数]:").append(stringBuilder.toString());
        }
        log.info(sb.toString());
    }

    //指定切点前的处理方法
    @AfterReturning(pointcut = "webLog()", returning = "result")
    public void doAfterReturning(Object result) {
        if (ObjectUtils.isEmpty(result)) {
            return;
        }
        String resultStr = JSON.toJSONString(result);
        JSONObject jsonString = JSONObject.parseObject(resultStr);
        String code = jsonString.getString("code");
        String message = jsonString.getString("message");
        long consum = System.currentTimeMillis() - threadLocal.get();
        threadLocal.remove();
        log.info("[返回结果]:" + "code:" + code + "," + "message:" + message + "[耗时]:" + consum + "ms");
    }

}
